#include "hf_ringbuf.h"
#include "hf_core_common.h"

void hf_ringbuf_init(struct hf_ringbuf *ring, uint8_t *pool, uint32_t size)
{
    memset(pool, 0, size);
    /* initialize read and write index */
    ring->read_index = 0;
    ring->write_index = 0;

    /* set buffer pool and size */
    ring->buffer_ptr = pool;
    ring->buffer_size = size;
}

int8_t hf_ringbuf_write(struct hf_ringbuf *ring, uint8_t ch)
{
    if (ring->read_index == ((ring->write_index + 1) % ring->buffer_size)) // 当写指针的下一个位置等于读指针的位置时，那么 ringbuffer 为满。
    {
        return ERR_BUF_FULL;
    }
    else
    {
        ring->buffer_ptr[ring->write_index] = ch;
        ring->write_index = (ring->write_index + 1) % ring->buffer_size;
        return ERR_OK;
    }
}

int8_t hf_ringbuf_read(struct hf_ringbuf *ring, uint8_t *ch)
{
    if (ring->read_index == ring->write_index) // 读写指针的位置相等时，说明 ringbuffer 为空。
    {
        return ERR_BUF_EMPTY;
    }
    else
    {
        *ch = ring->buffer_ptr[ring->read_index];
        ring->read_index = (ring->read_index + 1) % ring->buffer_size;
        return ERR_OK;
    }
}

int8_t hf_ringbuf_clean(struct hf_ringbuf *ring)
{
    memset(ring->buffer_ptr, 0, ring->buffer_size);
    
    ring->read_index = 0;
    ring->write_index = 0;

    return ERR_OK;
}

uint32_t hf_ringbuf_get_used_size(struct hf_ringbuf *ring)
{
    uint32_t used_size;
    
    if (ring->write_index >= ring->read_index)
    {
        // 写指针在读指针之后或相等（正常情况）
        used_size = ring->write_index - ring->read_index;
    }
    else
    {
        // 写指针在读指针之前（写指针已经绕一圈）
        used_size = ring->buffer_size - ring->read_index + ring->write_index;
    }
    
    return used_size;
}

uint32_t hf_ringbuf_get_free_size(struct hf_ringbuf *ring)
{
    // 由于满时会预留一个字节，所以可用空间 = 总大小 - 已用大小 - 1
    return ring->buffer_size - hf_ringbuf_get_used_size(ring) - 1;
}
